﻿namespace TheoryProject
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    /// <summary>
    /// Form 1 -Task1 form -
    /// </summary>
    public partial class Form1 : Form
    {
        /// <summary>
        /// list of final states
        /// </summary>
        private List<int> finalStates = new List<int>();

        /// <summary>
        /// list of transitions
        /// </summary>
        private List<Task1.Transition> transitions = new List<Task1.Transition>();

        /// <summary>
        /// Initializes a new instance of the <see cref="Form1"/> class.
        /// </summary>
        public Form1()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Handles the 1 event of the btnAddTransition_Click control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void BtnAddTransition_Click_1(object sender, EventArgs e)
        {
            try
            {
                string currentState = this.lblLeftBracket.Text + this.txtState.Text + this.lblFirstComma.Text + this.txtInputChar.Text + this.lblRightBracket.Text;
                string nextState = "   " + this.lblEqualAndLeftBracket.Text + this.txtNextState.Text + this.lblResFirstComma.Text + this.txtOutputChar.Text + this.lblResSecondComma.Text + this.txtDirection.Text + this.lblLastBracket.Text;
                string currentTransition = currentState + nextState;

                if (this.txtDirection.Text != string.Empty && this.txtInputChar.Text != string.Empty && this.txtNextState.Text != string.Empty && this.txtOutputChar.Text != string.Empty && this.txtState.Text != string.Empty)
                {
                    if (this.lstTransitions.Items.Contains(currentTransition))
                    {
                        MessageBox.Show("This Transition is already exisitng!");
                    }
                    else if (this.lstChecking.Items.Contains(currentState))
                    {
                        MessageBox.Show("This transition is already having another destination");
                    }
                    else
                    {
                        Task1.Transition tempTransition = new Task1.Transition();

                        // state
                        string stateTemp = this.txtState.Text;
                        stateTemp = stateTemp.Substring(1);
                        int stateNumber = int.Parse(stateTemp);
                        tempTransition.State = stateNumber;

                        // char
                        string character = this.txtInputChar.Text;

                        if (character[0] == '^')
                        {
                            tempTransition.InputChar = '\0';
                        }
                        else
                        {
                            tempTransition.InputChar = character[0];
                        }

                        // next state
                        stateTemp = this.txtNextState.Text;
                        stateTemp = stateTemp.Substring(1);
                        stateNumber = int.Parse(stateTemp);
                        tempTransition.NextState = stateNumber;

                        // char
                        character = this.txtOutputChar.Text;
                        if (character[0] == '^')
                        {
                            tempTransition.OutputChar = '\0';
                        }
                        else
                        {
                            tempTransition.OutputChar = character[0];
                        }

                        // Direction
                        if (this.txtDirection.Text[0] == 'R' || this.txtDirection.Text[0] == 'r')
                        {
                            tempTransition.Direction = Task1.Direction.RIGHT;
                        }
                        else if (this.txtDirection.Text[0] == 'L' || this.txtDirection.Text[0] == 'l')
                        {
                            tempTransition.Direction = Task1.Direction.LEFT;
                        }
                        else if (this.txtDirection.Text[0] == 'S' || this.txtDirection.Text[0] == 's')
                        {
                            tempTransition.Direction = Task1.Direction.STAY;
                        }
                        else
                        {
                            MessageBox.Show("Direction Invalid");
                            return;
                        }

                        this.lstTransitions.Items.Add(currentTransition);
                        this.lstChecking.Items.Add(currentState);
                        this.transitions.Add(tempTransition);
                    }
                }
                else
                {
                    MessageBox.Show("Please enter the transition in it`s correct form");
                }

                this.txtState.Text = string.Empty;
                this.txtInputChar.Text = string.Empty;
                this.txtNextState.Text = string.Empty;
                this.txtOutputChar.Text = string.Empty;
                this.txtDirection.Text = string.Empty;
            }
            catch 
            {
                MessageBox.Show("Error Invalid data");
            }
        }

        /// <summary>
        /// Handles the Click event of the btn_AddFinalState control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Btn_AddFinalState_Click(object sender, EventArgs e)
        {
            try
            {
                string finalState = "q " + this.txtBox_finalState.Text;
                if (!this.lst_FinalStates.Items.Contains(finalState))
                {
                    string stateTemp = this.txtBox_finalState.Text;
                    int stateNumber = int.Parse(stateTemp);
                    this.finalStates.Add(stateNumber);

                    this.lst_FinalStates.Items.Add(finalState);
                    this.txtBox_finalState.Text = string.Empty;
                }
                else
                {
                    MessageBox.Show("This Final state is already exist!");
                }
            }
            catch 
            {
                MessageBox.Show("Enter Valid Number ");
            }
        }

        /// <summary>
        /// Handles the Click event of the btn_Simulate control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Btn_Simulate_Click(object sender, EventArgs e)
        {
            try
            {
                Task1.Transition[] transitionFunctions = this.transitions.ToArray();
                string tape = (this.txtBox_Tape.Text == string.Empty) ? "\0" : this.txtBox_Tape.Text;
                char[] tapeChar = tape.ToCharArray();
                List<char> ch = new List<char>(tapeChar);

                int[] finalS = this.finalStates.ToArray();
                Task1.TuringMachine tr = new Task1.TuringMachine(transitionFunctions, ch, finalS);
                SimulationForm sim = new SimulationForm(tr);
                sim.Show();
            }
            catch 
            {
                MessageBox.Show("Error \n Check that you entered all TM parameters ");
            }
        }

        /// <summary>
        /// Handles the Click event of the button1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                Task1.Transition[] transitionFunctions = this.transitions.ToArray();
                string tape = (this.txtBox_Tape.Text == string.Empty) ? "\0" : this.txtBox_Tape.Text;

                char[] tapeChar = tape.ToCharArray();
                List<char> ch = new List<char>(tapeChar);

                int[] finalS = this.finalStates.ToArray();
                Task1.TuringMachine tr = new Task1.TuringMachine(transitionFunctions, ch, finalS);

                bool process = tr.Process();
                if (process)
                {
                    tapeChar = tr.Tape.ToArray();
                    if (this.rbAcceptors.Checked)
                    {
                        this.txtBox_Tape.Text = "Accepted State Tape : " + new string(tapeChar);
                    }
                    else
                    {
                        this.txtBox_Tape.Text = new string(tapeChar);
                    }
                }
                else
                {
                    this.txtBox_Tape.Text = "Reject State";
                }
            }
            catch
            {
                MessageBox.Show("Error \n Check that you entered all TM parameters ");
            }
        }

        /// <summary>
        /// Handles the Click event of the btnReadFromFile control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void BtnReadFromFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog op = new OpenFileDialog();
                if (op.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    List<Task1.Transition> tr = FileReader.ReadFromFile(op.FileName);
                    for (int i = 0; i < tr.Count; i++)
                    {
                        char chD = '\0';
                        char chI = '\0';
                        char cho = '\0';

                        if (tr[i].Direction == Task1.Direction.RIGHT)
                        {
                            chD = 'R';
                        }
                        else if (tr[i].Direction == Task1.Direction.LEFT)
                        {
                            chD = 'L';
                        }
                        else if (tr[i].Direction == Task1.Direction.STAY)
                        {
                            chD = 'S';
                        }

                        if (tr[i].InputChar == '\0')
                        {
                            chI = '^';
                        }
                        else
                        {
                            chI = tr[i].InputChar;
                        }

                        if (tr[i].OutputChar == '\0')
                        {
                            cho = '^';
                        }
                        else
                        {
                            cho = tr[i].OutputChar;
                        }

                        string s = "(q" + tr[i].State + "," + chI + ") = (q" + tr[i].NextState + "," + cho + "," + chD + ")";
                        this.lstTransitions.Items.Add(s);
                    }

                    this.transitions = tr;
                }
            }
            catch 
            {
                MessageBox.Show("Invalid File Format");
            }
        }
    }
}
